#ifndef BLUETOOTHWIDEGET_H
#define BLUETOOTHWIDEGET_H

#include <QWidget>
#include <QListWidgetItem>
#include <QDebug>
#include "./plugIn/QSimpleLed.h"
#include "./plugIn/loadingdialog.h"
#include "serialportwideget.h"
#include <QMessageBox>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
#include <QTest>
#include "mythread.h"
#include "./heatMap/qcustomplot.h"
#include "./heatMap/heatmapper.h"
#include "./heatMap/gradientpalette.h"
#include "./plugIn/serialport.h"

using namespace std;

extern QList<int>
    frequency_right_pressure,frequency_left_pressure,
    nine_pressure_data_right,nine_pressure_data_list_original_location_right,nine_pressure_data_temp_right,
    nine_pressure_data_left,nine_pressure_data_list_original_location_left,nine_pressure_data_temp_left;


QT_BEGIN_NAMESPACE
class QImage;
QT_END_NAMESPACE

class HeatMapper;
class GradientPalette;

namespace Ui {
class BluetoothWideget;
}

class BluetoothWideget : public QWidget
{
    Q_OBJECT

public:
    enum {
        DEFAULT_RADIUS = 80,
        DEFAULT_OPACITY = 220,
        DEFAULT_WIDTH = 255
    };

    /*菜单模块*/
    QMenu* menu[10];
    QAction* act[10];
    QMenuBar* menuBar ;
    QStatusBar* status ;

    explicit BluetoothWideget(QWidget *parent = nullptr);
    ~BluetoothWideget();
protected:

    /** 为左右脚组件，重写eventFilter事件过滤器
    *
    *  @param:  *watched 所过滤的组件
    *  @param:  *event  触发事件
    *  @return: void
    *  @note:   当组件为左右脚时并且触发绘画事件，便会进行处理
    *  @see:
    */
    bool eventFilter(QObject *watched, QEvent *event);

private:

    /*对话框*/
    Ui::BluetoothWideget *ui;
    LoadingDialog *loadingDialog;
    serialPortWideget *portWideget;
    MyThread *mythreadObject;
    CSerialPort cserialport;



    /*指示灯*/
    QSimpleLed *stepLed01 = nullptr;
    QSimpleLed *leftLed = nullptr;
    QSimpleLed *rightLed = nullptr;

    \
    /*x轴 y轴*/
    double timeX;
    int allPRange = 0,allPRangeR = 0,allPRangeL =0;
    int FMBPdata1 = 0 , FMBPdata2 = 0 ,FMBPdata3 = 0,FMBPdata = 0,FMBPRange = 0,FMBPRangeR = 0,FMBPRangeL = 0;
    int FBPdata1 = 0 , FBPdata2 = 0 ,FBPdata = 0,FBPRange = 0,FBPRangeR = 0,FBPRangeL = 0;
    int IOPdata1 = 0 , IOPdata2 = 0 ,IOPdata = 0,IOPRange = 0,IOPRangeR = 0,IOPRangeL = 0;

    /*游标*/
    QCPItemTracer* tracer;    //游标点
    QCPItemText* tracerLabel;    //游标框
    QCPGraph *selectedGraph;    //选中的曲线上显示游标
    double x,y;  //选中的曲线上鼠标移动的x，y位置


    /*时间*/
    QTimer *timer;//每隔15ms触发一次连接
    double *detectionTime; //设置测试时间
   double current_time_stop = 9999999999;  //暂停按钮按下时的时间

    int printContentChoose = 0; //下载选择模式
    QString save_floder,work_floder;    //下载以及上传文件的文件夹


    int modesNumber = 0;//选择模式的数量
    /*画坐标图*/
    typedef struct
    {
        QCPGraph *pGraph1_1;
        QCPGraph *pGraph1_2;
        QCPGraph *pGraph1_3;
        QCPGraph *pGraph1_4;
        QCPGraph *pGraph1_5;
        QCPGraph *pGraph1_6;
        QCPGraph *pGraph1_7;
        QCPGraph *pGraph1_8;
        QCPGraph *pGraph1_9;
    }allGraph;

    typedef struct
    {
        QCPGraph *FBGraph1_1;
        QCPGraph *FBGraph1_2;

    }frontBackGraph;

    typedef struct
    {
        QCPGraph *FMBpGraph1_1;
        QCPGraph *FMBpGraph1_2;
        QCPGraph *FMBpGraph1_3;

    }frontMidBackGraph;

    typedef struct
    {
        QCPGraph *IOGraph1_1;
        QCPGraph *IOGraph1_2;

    }insideOutsideGraph;

    typedef struct
    {
        QCPGraph *BGraph1_1;
        QCPGraph *BGraph1_2;

    }bodyGraph;

    typedef struct
    {
        QCustomPlot *plot;
        allGraph graph;
    }allPressure;

    typedef struct
    {
        QCustomPlot *plot;
        frontBackGraph graph;
    }frontBackPressure;

    typedef struct
    {
        QCustomPlot *plot;
        frontMidBackGraph graph;
    }frontMidBackPressure;

    typedef struct
    {
        QCustomPlot *plot;
        insideOutsideGraph graph;
    }insideOutsidePressure;

    typedef struct
    {
        QCustomPlot *plot;
        bodyGraph graph;
    }bodyPressure;

    typedef struct
    {
       allPressure allPressure;
       frontBackPressure frontBackPressure;
       frontMidBackPressure frontMidBackPressure;
       insideOutsidePressure insideOutsidePressure;
       bodyPressure bodyPressure;
    }FOOT;

    QList<QCustomPlot*> plotList,plotListR,plotListL,plotListAll;//customplot集合
    FOOT *double_foot,*left_foot,*right_foot;   //双脚、左脚单脚、右脚单脚

    /** 初始化串口窗口
    *
    *  @param:  void
    *  @return: void
    *  @note:   初始化串口,该窗口调用serialport第三方库，创建两个串口子线程，分别对应左右脚串口
    *  @see:
    */
    void initPortWidget();

    /** 初始化菜单
    *
    *  @param:  void
    *  @return: void
    *  @note:   初始化菜单，调用QMenu函数创建菜单
    *  @see:
    */
    void initMenu();

    /** 初始化指示灯
    *
    *  @param:  void
    *  @return: void
    *  @note:   初始化指示灯，调用QSimpleLed第三方库
    *  @see:
    */
    void initLamp();

    /** 双足,左右足坐标图初始化
    *
    *  @param:  void
    *  @return: void
    *  @note:   通过结构体创建对应的坐标图
    *  @see:
    */
    void initAllPressurePicture();

    /** 对应QCustomPlot*坐标图,更新QList<int>坐标数据绘图
    *
    *  @param:  QCustomPlot*    当前坐标图
    *  @param:  QList<int>      当前坐标数据
    *  @param:  int             当前坐标图表示位
    *  @return: void
    *  @note:   对应坐标图更新坐标数据绘图
    *  @see:
    */
    void showPlot(QCustomPlot*,QList<int>,int);


    // 绘图对象指针
    HeatMapper *mapper_right,*mapper_left;
    // 用于显示输出的图像
     QImage *canvas_right,*canvas_left;
    // 调色板
    GradientPalette *palette_;

    /** 初始化左右脚热力图数据
    *
    *  @param:  void
    *  @return: void
    *  @note:   初始化左右脚热力图数据
    *  @see:
    */
    void initHeatMapPicture();

    /** 热力图传值
    *
    *  @param:  pressure        原始压力数据
    *  @param:  sortedIndex     压力数据由大到小排序后索引
    *  @param:  pressureTemp    压力由大到小的排列数据
    *  @param:  type            左右脚标识位,0为右，1为左
    *  @return: void
    *  @note:   首先将最大的压力数据索引取出，并画出该点，之后再依次画出后续8个压力点数据
    *  @see:
    */
    void showHeatMap( QList<int> pressure, QList<int> sortedIndex ,QList<int> pressureTemp,int type);

    /** 压力数据传输以及热力图数据传输
    *
    *  @param:  void
    *  @return: void
    *  @note:   压力数据传输以及热力图数据传输
    *  @see:
    */
    void updateData();

signals:
    /** 发送右脚线程开启信号
    *
    *  @param:  void
    *  @return: void
    *  @note:   右脚线程开启
    *  @see:
    */
    void emitBeginSignal();

    /** 发送左脚线程开启信号
    *
    *  @param:  void
    *  @return: void
    *  @note:   左脚线程开启
    *  @see:
    */
    void emitBeginSignalLeft();



private slots:
    /** 对customPlot统一处理初始化,该坐标图的名称为plotName ; private槽函数
    *
    *  @param:  *customPlot 对应坐标图
    *  @param:  plotName    对应坐标图名称
    *  @return: void
    *  @note:   对customPlot统一处理初始化,该坐标图的名称为plotName
    *  @see:
    */
    void initPlot(QCustomPlot *customPlot,QString plotName);

    /** 将customPlot的图例与其坐标曲线同步连接 ; private槽函数
    *
    *  @param:  *customPlot 对应坐标图
    *  @return: void
    *  @note:   图例与坐标曲线同步连接
    *  @see:
    */
    void selectionChanged(QCustomPlot *customPlot);

    /** 通过定时器开始采集 ; private槽函数
    *
    *  @param:  void
    *  @return: void
    *  @note:   开始采集
    *  @see:
    */
    void timeBegin();

    /** 定时器溢出处理槽函数 ; private槽函数
    *
    *  @param:  void
    *  @return: void
    *  @note:   定时器溢出处理槽函数：用来生成曲线的坐标数据
    *  @see:
    */
    void TimeDataUpdate();

    /** 停止采集并删除定时器 ; private槽函数
    *
    *  @param:  void
    *  @return: void
    *  @note:   停止采集
    *  @see:
    */
    void timeStop();



//    void onSliderMoved(int);//进度条拖动
//    void onSliderReleased();//进度条释放
//    void onSliderClicked();//进度条点击

    /** 选择菜单项 ; private槽函数
    *
    *  @param:  *act      对应菜单项的行为
    *  @return: void
    *  @note:   选择菜单项，根据*act的名称来选择
    *  @see:
    */
    void trigerMenu(QAction *act);

    /** 鼠标移动位置，获取x轴坐标 ; private槽函数
    *
    *  @param:  e   鼠标移动事件
    *  @return: void
    *  @note:   鼠标移动位置，获取x轴坐标
    *  @see:
    */
    void mouseMove(QMouseEvent *e);

    /** 病人信息列表显示 ; private槽函数
    *
    *  @param:  object
    *  @return: void
    *  @note:   病人信息列表显示
    *  @see:
    */
    void searchUserInfo(QJsonObject object);

    /** 右键菜单 ; private槽函数
    *
    *  @param:  const QPoint&
    *  @return: void
    *  @note:   右键菜单
    *  @see:
    */
    void SlotCustomContextMenuRequested(const QPoint&);

    /** 右键删除病人文件 ; private槽函数
    *
    *  @param:  void
    *  @return: void
    *  @note:   右键删除病人文件
    *  @see:
    */
    void deleteItemFunction();

    /** 关闭总窗口 ; private槽函数
    *
    *  @param:  void
    *  @return: void
    *  @note:   关闭总窗口
    *  @see:
    */
    void on_closeButton_clicked();
};

#endif // BLUETOOTHWIDEGET_H
